package com.fgsort;

import java.awt.Color;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JTextField;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

//import org.jdom2.Document;


public class PanelHwCheck extends JPanel {

	public String sHwCfgFile = null; 
	public String sHwCfgXML = "c:/tmp/hwconfig/hwconfig.xml"; 
	
	private static final long serialVersionUID = 1L;
	private final JLabel lblHwCheck= new JLabel("Hardware Check");
	private final JSeparator separator_2 = new JSeparator();
	private final JSeparator separator = new JSeparator();
	private final JTextField txtHwCfgFile = new JTextField("d:/tmp/hwconfig/");
	private final JButton btnSelectHwCfg = new JButton("Select");
	private final JTextField txtExcelFile = new JTextField("");
	private final JButton btnCheck = new JButton("Check");
	private final JTextField txtStatus = new JTextField(10);
	private final JLabel lblConfig = new JLabel("Configuration");
	private final JTextField txtXmlHwCfg = new JTextField("d:/tmp/hwconfig/");
	private final JButton btnXmlSelect = new JButton("Select");
	
	public PanelHwCheck(String sPanelTitle) {
		
		GridBagLayout gridBagLayout = new GridBagLayout();
		gridBagLayout.columnWidths = new int[]{0, 0, 0, 0, 0, 0};
		gridBagLayout.columnWeights = new double[]{1.0, 1.0, 1.0, 1.0, 1.0};
		gridBagLayout.rowHeights = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
		gridBagLayout.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0};
//		gridBagLayout.columnWidths = new int[]{32, 0, 0, 0, 0};
//		gridBagLayout.rowHeights = new int[]{0, 0, 35, 0, 0, 26, 30, 30, 0, 0, 0, 0, 0, 28, -110, 0, 0};
//		gridBagLayout.columnWeights = new double[]{0.0, 0.0, 1.0, 1.0, 1.0};
//		gridBagLayout.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
		setLayout(gridBagLayout);
		
		setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.gray), sPanelTitle));
		
		GridBagConstraints gbc_separator = new GridBagConstraints();
		gbc_separator.insets = new Insets(0, 0, 5, 0);
		gbc_separator.fill = GridBagConstraints.BOTH;
		gbc_separator.gridwidth = 6;
		gbc_separator.gridx = 0;
		gbc_separator.gridy = 0;
		separator.setForeground(new Color(119, 136, 153));
		add(separator, gbc_separator);
		
		GridBagConstraints gbc_lblHwCheck = new GridBagConstraints();
		gbc_lblHwCheck.insets = new Insets(0, 0, 5, 0);
		gbc_lblHwCheck.gridwidth = 6;
		gbc_lblHwCheck.gridx = 0;
		gbc_lblHwCheck.gridy = 1;
		lblHwCheck.setForeground(Color.BLACK);
		lblHwCheck.setFont(new Font("Tahoma", Font.BOLD, 13));
		add(lblHwCheck, gbc_lblHwCheck);
		
		GridBagConstraints gbc_separator_2 = new GridBagConstraints();
		gbc_separator_2.insets = new Insets(0, 0, 5, 0);
		gbc_separator_2.fill = GridBagConstraints.BOTH;
		gbc_separator_2.gridwidth = 6;
		gbc_separator_2.gridx = 0;
		gbc_separator_2.gridy = 2;
		separator_2.setForeground(new Color(119, 136, 153));
		add(separator_2, gbc_separator_2);
		
		GridBagConstraints gbc_txtHwCfgFile = new GridBagConstraints();
		gbc_txtHwCfgFile.gridwidth = 5;
		gbc_txtHwCfgFile.insets = new Insets(0, 0, 5, 5);
		gbc_txtHwCfgFile.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtHwCfgFile.gridx = 0;
		gbc_txtHwCfgFile.gridy = 3;
		txtHwCfgFile.setEditable(false);
		txtHwCfgFile.setColumns(10);
		add(txtHwCfgFile, gbc_txtHwCfgFile);
		
		GridBagConstraints gbc_btnSelectHwCfg = new GridBagConstraints();
		gbc_btnSelectHwCfg.fill = GridBagConstraints.HORIZONTAL;
		gbc_btnSelectHwCfg.insets = new Insets(0, 0, 5, 0);
		gbc_btnSelectHwCfg.gridx = 5;
		gbc_btnSelectHwCfg.gridy = 3;
		btnSelectHwCfg.setToolTipText("select the .cfg file that contains the hardware config");
		btnSelectHwCfg.setFont(new Font("Tahoma", Font.PLAIN, 13));
		add(btnSelectHwCfg, gbc_btnSelectHwCfg);
		
		GridBagConstraints gbc_txtExcelFile = new GridBagConstraints();
		gbc_txtExcelFile.gridwidth = 5;
		gbc_txtExcelFile.insets = new Insets(0, 0, 5, 5);
		gbc_txtExcelFile.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtExcelFile.gridx = 0;
		gbc_txtExcelFile.gridy = 4;
		txtExcelFile.setEditable(false);
		txtExcelFile.setColumns(10);
		add(txtExcelFile, gbc_txtExcelFile);
		
		GridBagConstraints gbc_btnCheck = new GridBagConstraints();
		gbc_btnCheck.fill = GridBagConstraints.HORIZONTAL;
		gbc_btnCheck.insets = new Insets(0, 0, 5, 0);
		gbc_btnCheck.gridx = 5;
		gbc_btnCheck.gridy = 4;

		btnCheck.setToolTipText("check hw config faults and generate excel report");
		btnCheck.setFont(new Font("Tahoma", Font.PLAIN, 13));
		add(btnCheck, gbc_btnCheck);
		
		GridBagConstraints gbc_lblConfig = new GridBagConstraints();
		gbc_lblConfig.anchor = GridBagConstraints.WEST;
		gbc_lblConfig.gridwidth = 6;
		gbc_lblConfig.insets = new Insets(0, 0, 5, 0);
		gbc_lblConfig.gridx = 0;
		gbc_lblConfig.gridy = 9;
		lblConfig.setForeground(Color.DARK_GRAY);
		lblConfig.setFont(new Font("Tahoma", Font.BOLD, 11));
		add(lblConfig, gbc_lblConfig);
		
		GridBagConstraints gbc_txtXmlHwCfg = new GridBagConstraints();
		gbc_txtXmlHwCfg.gridwidth = 5;
		gbc_txtXmlHwCfg.insets = new Insets(0, 0, 5, 5);
		gbc_txtXmlHwCfg.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtXmlHwCfg.gridx = 0;
		gbc_txtXmlHwCfg.gridy = 10;
		txtXmlHwCfg.setToolTipText("Select the FG .xml file location");
		txtXmlHwCfg.setEditable(false);
		txtXmlHwCfg.setColumns(10);
		add(txtXmlHwCfg, gbc_txtXmlHwCfg);
		
		GridBagConstraints gbc_btnXmlSelect = new GridBagConstraints();
		gbc_btnXmlSelect.fill = GridBagConstraints.HORIZONTAL;
		gbc_btnXmlSelect.insets = new Insets(0, 0, 5, 0);
		gbc_btnXmlSelect.gridx = 5;
		gbc_btnXmlSelect.gridy = 10;
		btnXmlSelect.setToolTipText("Select the FG .xml file location");
		btnXmlSelect.setFont(new Font("Tahoma", Font.PLAIN, 13));
		add(btnXmlSelect, gbc_btnXmlSelect);
		
		GridBagConstraints gbc_txtStatus = new GridBagConstraints();
		gbc_txtStatus.gridwidth = 6;
		gbc_txtStatus.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtStatus.gridx = 0;
		gbc_txtStatus.gridy = 11;
		txtStatus.setText("status");
		txtStatus.setEditable(false);
		add(txtStatus, gbc_txtStatus);

	
		///button - select hw config file
		btnSelectHwCfg.addActionListener(new ActionListener() {
        	public void actionPerformed(ActionEvent e) {
        		sHwCfgFile = chooseFile(txtHwCfgFile.getText());
        		txtHwCfgFile.setText(sHwCfgFile);
        		txtExcelFile.setText(stripExtension(sHwCfgFile)+".xls");
        		}
        	}
        );
		
		///button - check hw config
		btnCheck.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				checkHwConfig(sHwCfgXML, sHwCfgFile);
			}
		});
		
		///button - select unsorted function group file
		btnXmlSelect.addActionListener(new ActionListener() {
        	public void actionPerformed(ActionEvent e) {
        		sHwCfgXML = chooseFile("d:/tmp/hwconfig/");
        		txtXmlHwCfg.setText(sHwCfgXML);
        		}
        	}
        );
		
	}

	private String chooseFile(String sFileLocation) {

		 String sfileName = null;
		  
		  //JFileChooser chooser = new JFileChooser(System.getProperty("user.dir"));
		 JFileChooser chooser = new JFileChooser(sFileLocation);
	      int option = chooser.showOpenDialog(PanelHwCheck.this);
	      if(option == JFileChooser.APPROVE_OPTION) {
	    	  txtStatus.setText("You chose "+((chooser.getSelectedFile()!=null)? chooser.getSelectedFile().getAbsoluteFile():"nothing"));
	    	  sfileName = chooser.getSelectedFile().getAbsoluteFile().toString();
	      }
	      if(option == JFileChooser.CANCEL_OPTION) {
	    	  txtStatus.setText("You canceled.");
	    	  sfileName = sFileLocation;
	       }
		  return sfileName;
	}

	public static String stripExtension(final String s)
	{
	    return s != null && s.lastIndexOf(".") > 0 ? s.substring(0, s.lastIndexOf(".")) : s;
	}

	///main check
    public void checkHwConfig(String sHwCfgXML, String txtHwCfgFile)
    {
  	
		List<String> lstHwCfgOrderNo = new ArrayList<String>();
		List<String> lstHwCfgParamValues = new ArrayList<String>();
		
		try {
			///fetch all order numbers from xml .cfg file
			lstHwCfgOrderNo.addAll(getHwCfgElementValuesXML(sHwCfgXML, "orderno"));
			
			for (int i = 0; i < lstHwCfgOrderNo.size(); i++) {
				fireOptionEvent(new OptionEvent(this, lstHwCfgOrderNo.get(i).toString()));
				//System.out.println(lstFunctionGroupsXmlNames.get(i).toString());
			}
			
			///fetch all parameter rule sets from xml .cfg file
			lstHwCfgOrderNo.addAll(getHwCfgParamValuesXML(sHwCfgXML, "description"));
			
			for (int i = 0; i < lstHwCfgParamValues.size(); i++) {
				fireOptionEvent(new OptionEvent(this, lstHwCfgParamValues.get(i).toString()));
				//System.out.println(lstFunctionGroupsXmlNames.get(i).toString());
			}

			
			
			
			
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
    }
	
    ///xml parser - get all the elements of specified order number 
    public ArrayList<String> getHwCfgElementValuesXML(String sFileName, String sOrderNo) throws IOException, ParserConfigurationException, SAXException {
    		
    		String  sNodeListValue;
    		ArrayList<String> lstElements = new ArrayList<String>();
    		
    		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            File file = new File(sFileName);
            if (file.exists()) {

            	Document doc = db.parse(file);
                Element docEle = doc.getDocumentElement();
                NodeList deviceNodeList = docEle.getElementsByTagName("device");
           
                if (deviceNodeList != null && deviceNodeList.getLength() > 0) {
                    for (int i = 0; i < deviceNodeList.getLength(); i++) {
                         Node node = deviceNodeList.item(i);
                         //fireOptionEvent(new OptionEvent(this, node.getNodeName()));
                         if (node.getNodeType() == Node.ELEMENT_NODE) {
                            Element e = (Element) node;
                            NodeList nodeListName = e.getElementsByTagName(sOrderNo);
                            sNodeListValue = nodeListName.item(0).getChildNodes().item(0).getNodeValue().trim();
                            lstElements.add(sNodeListValue);
                        }
                    }
                }
            }
            else {
            	fireOptionEvent(new OptionEvent(this, "file does not exist!"));
            }
            
			return lstElements;
    }

    ///xml parser - get parameter rule set (values) of specified order number 
    public ArrayList<String> getHwCfgParamValuesXML(String sFileName, String sElementType ) throws IOException, ParserConfigurationException, SAXException {
    		
    		String  sNodeListValue;
    		ArrayList<String> lstElements = new ArrayList<String>();
    		
    		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            File file = new File(sFileName);
            if (file.exists()) {

            	Document doc = db.parse(file);
                Element docEle = doc.getDocumentElement();
                NodeList deviceNodeList = docEle.getElementsByTagName("device");
           
                if (deviceNodeList != null && deviceNodeList.getLength() > 0) {
                    for (int i = 0; i < deviceNodeList.getLength(); i++) {
                         Node node = deviceNodeList.item(i);
                         //fireOptionEvent(new OptionEvent(this, node.getNodeName()));
                         if (node.getNodeType() == Node.ELEMENT_NODE) {
                            Element e = (Element) node;
                            NodeList nodeListName = e.getElementsByTagName(sElementType);
                            for (int j = 0; j < nodeListName.getLength(); j++) {
	                            sNodeListValue = nodeListName.item(j).getChildNodes().item(0).getNodeValue().trim();
	                            lstElements.add(sNodeListValue);
                            }
                        }
                    }
                }
            }
            else {
            	fireOptionEvent(new OptionEvent(this, "file does not exist!"));
            }
            
			return lstElements;
    }

    
    
    ///Debug output - Event Listener
    public void fireOptionEvent(OptionEvent event) {
        Object[] listeners = listenerList.getListenerList();
         
        for(int i=0; i < listeners.length; i += 2) {
            if(listeners[i] == OptionListener.class) {
                ((OptionListener)listeners[i+1]).detailEventOccurred(event);
            }
        }
    }
    
    public void addOptionListener(OptionListener listener) {
        listenerList.add(OptionListener.class, listener);
    }
    
	

    
    
}
